package fileshare.control;
/**
 
 * main function in which there is a timer thread will try to update the queue for
 * these 2 kind of peers automatically
 * let this class control also the interest list who contains the peer like you
 * @author Administrator
 *
 */

import java.util.Random; 
import java.util.Arrays;

import fileshare.fileprocessing.log;
import fileshare.network.peerProcess;
public class preferque
{
 private volatile int[]prefer=new int[7];// +1 make sure the positive peer index
 private volatile int[]trefer=new int[7];
 private volatile int[]interque=new int[7];
 private volatile int[]download=new int[7];
 private volatile int[]nonrefer=new int[7];
 private volatile int optimistic=-1;
 private volatile int intrnum=0;
 private volatile boolean preport=false;
 
 private volatile int []chokelist={-2,-2,-2,-2,-2,-2,-2,-2};//initialize the choke list,this list will be checked every cycle 
 //by the peer main thread to decide whether to choke or unchoke a certain peer
public preferque()
{
	for(int i=1;i<7;i++)
	{
		prefer[i]=0;
		trefer[i]=0;
		nonrefer[i]=0;
		interque[i]=0;
		download[i]=0;
	}
	
}

public   void updateprefer()throws Exception
{
	
	for(int i=1;i<7;i++)
		{
		nonrefer[i]=0;//empty the old data
		trefer[i]=0;
		}
	this.getnonprefer();//put all the nonprefer peers in tprefer which is also in the interque
	//if the file is complete
	//then chose 2 peer randomly from the interested queue
	//put them in temporary preferreed queue
	if(peerProcess.completeflag)
	{
		this.rdmchosepre();
		
	}
	else
		this.downloadcac();
	//check the current prefered ,check those peers who are not in the temporary queue
	String preferlist="";
	for(int i=1;i<7;i++)
	{
		if(trefer[i]==1)
			preferlist="peer: "+i+" , "+preferlist;
	}
	boolean flag=false;
	for(int i=1;i<=6;i++)
	{
		if(prefer[i]==1&&trefer[i]==0)
		{
			chokelist[i]=0;//choke it
			prefer[i]=0;
			//taskthread.makemsg(1, 0, 0, 0);
			preport=true;
		}
		if(prefer[i]==0&&trefer[i]==1)
		{
			chokelist[i]=1;//unchoke it
			prefer[i]=1;
			preport=true;
			
			
		}
		/*if(prefer[i]==1&&trefer[i]==1)
		{
			
			preport=false;
		}*/
		flag=flag||preport;
	}
	String content="has the perferlists "+preferlist+"\n";
	if(preport)
	log.write2log(content);
	//evict them by sendmsg(choke)
	//check the temporary preffere queue 
	//if they are in the choke list
	//sendmsg (unchoke)
   // 
	//
	//if the file is not complete
	
	//caculate the download rate from the interested queue,
	//{ maintain a queue called download queue [6],initalize t0 0,when receive a piece 
	//in creasing the correspongding peer inside by +1 ,after the update prefer,zero it.
	//
	//}
	//
	//if the file is complete then the prefer is chosen randomly
	System.out.println("updateprefer function in preferque");
	
}
public  void updateopt()throws Exception//chose the optimistic peers
{
	Random ranOpt=new Random();
	while(true)
	{
		int optcho=ranOpt.nextInt(60)%7;
		if(optcho==0)
			continue;
		if(chokelist[optcho]==0&&interque[optcho]==1)
			{
			chokelist[optcho]=1;//unchoke it
			String content="has the optimistic peer "+optcho+"\n";
			log.write2log(content);
			break;
			}
			
			
	}
	System.out.println("updateopt function in preferque");
}
private   void downloadcac()
{
	int []td=download;
	Arrays.sort(td);//sort the download rate 
	for(int i=6,count=2;i>0&&count>0;i--)//sort the 2 max download peers into trefer
	{
		for(int j=1;j<7;j++)
		{
			if(j==peerProcess.self_index)
				continue;
			if(td[i]==download[j])
			{
				if(interque[j]==1&&trefer[j]!=1)
				{trefer[j]=1;
				count--;
				
				break;
				}
				continue;
			}
			else
				continue;
		}
	}
	     
	for(int i=1;i<7;i++)
		download[i]=0;//resotre the value of download to empty
}
private   void getnonprefer()//get non-prefer in the interque
{
	for(int i=1;i<7;i++)
	{
		if(i==peerProcess.self_index)
			continue;
		if(nonrefer[i]!=1&&prefer[i]==0&&interque[i]==1)
		{
			nonrefer[i]=1;
			
		}
		
	}
}
//choose randomly from the interesting queue for a peer
private   void rdmchosepre()
{
	if(intrnum<3)//scan the interque to get out all the peers
	{
		for(int i=1;i<7;i++)
		{
			if(interque[i]==1)
				trefer[i]=1;
		}
		return;
	}
	Random rmobj=new Random();
	int num=2;
	while(true&&num>0)
	{
		
		int rmpiece=rmobj.nextInt(80)%7;
		if(rmpiece==peerProcess.self_index||rmpiece==0)
			continue;
		if(interque[rmpiece]==1&&trefer[rmpiece]==0)
		{
			trefer[rmpiece]=1;
			num--;
		}
		
			
	}
	
	
}

/**
 * add peerindex into the interested queue
 * @param peerindex
 */
public  void addinterest(int peerindex)
{
	interque[peerindex]=1;//if the peer stat is 1 means it is in
	intrnum++;
}
public   void rminterest(int peerindex)
{
	interque[peerindex]=0;//if the peer stat is 1 means it is in
	intrnum--;
}
/*public void seeChokelist()
{
	for(int i=1;i<7&&i!=peer.self_index;i++)
	{
		if(chokelist[i]==1)
			//unchoke it
			
	}
}*/
/**
 * try to check whether a certain peer is choked or not if choke return 0; if notchoked return 1
 *if the value is 1 or 0 means the value is newly changed,and change them to 2 and -1 respectively
 *so when o or 1 is received by the caller he knew the value is newly changed 
 */
public  int checkChoke(int pid)
{
	if(chokelist[pid]==1)
		{chokelist[pid]=2;return 1;}
	if(chokelist[pid]==2)
	{return 2;}
	else
		if(chokelist[pid]==0)
			{chokelist[pid]=-1;return 0;}
	if(chokelist[pid]==-1)
	{return -1;}
	else
		return -100;
}
/*// generate a random number
public int geneRandom(int scope)
{
	Random rand=new Random();
	while(true)
	{
		int gen=rand.nextInt(80);
		System.out.println("the number is "+gen%7);
		
	}
	
}*/
}

	



